# -*- coding: utf-8 -*-
"""
 ----------------------------------------
|File Name:     core
|Author:        WYT
|date:          2021/7/2
 ----------------------------------------
|  Change Activity:
|                   2021/7/2:
-----------------------------------------
"""
import ctypes
import html
import sys
import urllib.parse

from util.encryption_password.sm2 import sm2cipher


class CryptoJs(object):

    @classmethod
    def int_overflow(cls, val):
        maxint = 2147483647
        if not -maxint - 1 <= val <= maxint:
            val = (val + (maxint + 1)) % (2 * (maxint + 1)) - maxint - 1
        return val

    @classmethod
    def unsigned_right_shitf(cls, n, i):
        # 数字小于0，则转为32位无符号uint
        if n < 0:
            n = ctypes.c_uint32(n).value
        # 正常位移位数是为正数，但是为了兼容js之类的，负数就右移变成左移好了
        if i < 0:
            return -cls.int_overflow(n << abs(i))
        # print(n)
        return cls.int_overflow(n >> i)

    @classmethod
    def stringify(cls, words, sig_bytes):
        hex_chars = []
        for i in range(0, sig_bytes):
            bite = (cls.unsigned_right_shitf(words[cls.unsigned_right_shitf(i, 2)], (24 - (i % 4) * 8))) & 0xff
            hex_chars.append(str(hex(cls.unsigned_right_shitf(bite, 4))))
            hex_chars.append(str(hex(bite & 0x0f)))
        # python 中 十六进制数前 有 0x 符号 需要先替换掉
        return "".join(hex_chars).replace("0x", "")

    def Latin1_parse(self, latin1_str):
        latin1str_length = len(latin1_str)
        words = []
        for i, c in enumerate(latin1_str):
            a = self.unsigned_right_shitf(i, 2)
            while True:
                if len(words) < a + 1:
                    words.append(0)
                else:
                    break
            # print("ord_res:", ord(latin1Str[i]))
            words[a] |= (int(ord(latin1_str[i]) & 0Xff) << (24 - (i % 4) * 8))
        return self.stringify(words, latin1str_length)

    def enc_utf8_parse(self, utf8_str):
        url_encode_res = urllib.parse.unquote(utf8_str)
        unescape_res = html.unescape(url_encode_res).encode(sys.getfilesystemencoding()).decode('utf-8')

        res = self.Latin1_parse(unescape_res)
        return res


if __name__ == '__main__':
    a = CryptoJs()
    res = a.enc_utf8_parse("Hz123456")
    print(res)
    print(sm2cipher.str2_bytes(res))
